home *** CD-ROM | disk | FTP | other *** search
/ Aminet 15 / Aminet 15 - Nov 1996.iso / Aminet / comm / bbs / s342q16.lha / confg.c < prev    next >
C/C++ Source or Header  |  1996-09-01  |  46KB  |  1,833 lines

  1. /*
  2. *           confg.c
  3. *
  4. * Configuration program for Citadel bulletin board system.
  5. */
  6. #define CONFIGURE
  7. #include "ctdl.h"
  8. #include "math.h"
  9. /*
  10. *       History
  11. *
  12. * 85Dec26 HAW  Add CALL-LOG define.
  13. * 85Nov15 HAW  MS-DOS library update.
  14. * 85Oct27 HAW  Kill CERMETEK.
  15. * 85Oct17 HAW  Add paramVers, change bauds to array, searchBaud chg.
  16. * 85Oct16 HAW  Kill CLOCK, add officeStuff.
  17. * 85Aug24 HAW  Add duomessage file, NETDISK specification.
  18. * 85Jul07 HAW  Update so won't go through total recon. on init.
  19. * 85May27 HAW  Start stuffing in auto-networking stuff.
  20. * 85May22 HAW  Start conversion to make log file size sysop selectable.
  21. * 85May11 HAW  Make "Lobby" sysop definable
  22. * 85May06 HAW  Add bail out code.
  23. * 85May05 HAW  Add helpDisk parameter for 3 disk system.
  24. * 85Apr10 HAW  Fix logSort, alphabetize file.
  25. * 85Mar11 HAW  Put all user functions in this file.
  26. * 85Feb18 HAW  Add baud search stuff.
  27. * 85Jan20 HAW  Use MSDOS #define for date stuff.
  28. * 84Sep05 HAW  Isolate strangeness in compiler's library.  See note.
  29. * 84Aug30 HAW  Onwards to MS-DOS!
  30. * 84Apr08 HAW  Update to BDS C 1.50a begun.
  31. * 82Nov20 CrT  Created.
  32. */
  33. /*
  34. *       Contents
  35. *
  36. * dGetWord()    reads a word off disk
  37. * init()      system startup initialization
  38. * main()      main controller
  39. * illegal()   abort bottleneck
  40. * msgInit()   sets up cfg.catChar, catSect etc.
  41. * zapMsgFile()    initialize ctdlmsg.sys
  42. * realZap()   does work of zapMsgFile()
  43. * indexRooms()    build RAM index to ctdlroom.sys
  44. * noteRoom()    enter room into RAM index
  45. * zapRoomFile()   erase & re-initialize ctdlroom.sys
  46. * setSpace()    set default disk and user#
  47. * hash()      hashes a string to an integer
  48. * logInit()   builds the RAM index to CTDLLOG.SYS
  49. * noteLog()   enters a userlog record into RAM index
  50. * sortLog()   sort CTDLLOG by time since last call
  51. * wrapup()    finishes and writes ctdlTabl.sys
  52. * zapLogFile()    erases & re-initializes CTDLLOG.SYS
  53. */
  54. /*
  55. *   Strangenesses   (Hue, Jr., 12Sep84)
  56. * Have discovered that the line:
  57. * sscanf(line, "\"%s\"", str);
  58. * is not parsed the same way by this compiler as it is by BDS;
  59. * this is highly unfortunate and excrable.  So, all porters
  60. * should note that scanf() is not, in any way, "portable."  If
  61. * BDS is "non-standard", then the standard sucks.
  62. */
  63. #define BAUDS "Valid SYSBAUD values: 0=300, 1=1200, 2=2400, 3=4800,\n4=9600, 5=14.4, 6=19.2, 7=38.4, 8=57.6"
  64. struct GenList
  65.   {
  66.   char *GenName;
  67.   int  GenVal;
  68.  
  69.   };
  70. extern FILE *msgfl, *msgfl2;    /* file descriptor for the msg file */
  71. char   *baseRoom;
  72. int   mailCount=0;
  73. char   msgZap =  FALSE,
  74. logZap =  FALSE,
  75. roomZap = FALSE;
  76. char  FirstInit = FALSE;
  77. char  ReInit = FALSE;
  78. static DATA_BLOCK sectBuf;
  79. long FloorSize;
  80. int  DefaultPrefix;
  81. void  Zap_Nodes_Message_Index(void);  /* zap last netted message */
  82.  
  83.  
  84. static char NetParse(char *line, int *offset, char *var, int arg, int SetVal);
  85. extern SListBase Events;    /* event list     */
  86. extern CONFIG    cfg;      /* The configuration variable  */
  87. extern MessageBuffer   msgBuf;    /* The -sole- message buffer  */
  88. extern NetBuffer netBuf;
  89. extern rTable    *roomTab;        /* RAM index of rooms   */
  90. extern aRoom     roomBuf;        /* room buffer     */
  91. extern EVENT     *EventTab;
  92. extern int       thisRoom;        /* room currently in roomBuf  */
  93. extern int       thisNet;
  94. extern LogTable  *logTab;        /* RAM index of pippuls    */
  95. extern logBuffer logBuf;    /* Log buffer of a person       */
  96. extern SListBase Serves;
  97. extern FILE      *logfl;    /* log file descriptor    */
  98. extern FILE      *roomfl;        /* file descriptor for rooms */
  99. extern FILE      *netfl;
  100. extern LogTable  *logTab;        /* RAM index of pippuls    */
  101. extern int       thisLog;        /* entry currently in logBuf */
  102. extern NetTable  *netTab;
  103. void CheckNet( void );
  104. /*
  105. * init()
  106. *
  107. * The master system initialization.
  108. */
  109. void init(int attended)
  110.   {
  111.   extern char   *W_R_ANY;
  112.   extern char   *R_W_ANY;
  113.   extern char   *READ_ANY;
  114.   extern char   *WRITE_ANY;
  115.   unsigned char c;
  116.   SYS_FILE      tempName;
  117.   extern int    errno, _doserrno;
  118.   cfg.sizeLTentry = sizeof(*logTab);
  119.   cfg.BoolFlags.debug       = FALSE;
  120.   cfg.BoolFlags.noChat      = TRUE;
  121.   /* shave-and-a-haircut/two bits pause pattern for ringing sysop: */
  122.   cfg.shave[0]    = 40;
  123.   cfg.shave[1]    = 20;
  124.   cfg.shave[2]    = 20;
  125.   cfg.shave[3]    = 40;
  126.   cfg.shave[4]    = 80;
  127.   cfg.shave[5]    = 40;
  128.   cfg.shave[6]    =250;
  129.   /* initialize input character-translation table:  */
  130.   for (c = 0;  c < '\40';  c++)
  131.     {
  132.     cfg.filter[c] = '\0';    /* control chars -> nulls  */
  133.  
  134.     }
  135.   cfg.filter[1] = 'y';    /* fix from 3.43, carried back to this version */
  136.   cfg.filter[7] = '7';
  137.   for (c='\40'; c < 128;   c++)
  138.     {
  139.     cfg.filter[c] = c;        /* pass printing chars  */
  140.  
  141.     }
  142.   cfg.filter[SPECIAL]     = SPECIAL;
  143.   cfg.filter[CNTRLl]      = CNTRLl;
  144.   cfg.filter[DEL      ]   = BACKSPACE;
  145.   cfg.filter[BACKSPACE]   = BACKSPACE;
  146.   cfg.filter[XOFF     ]   = XOFF     ;
  147.   cfg.filter[XON      ]   = XON      ;
  148.   cfg.filter['\r'     ]   = NEWLINE  ;
  149.   cfg.filter[CNTRLO   ]   = 'N'      ;
  150.   mvToHomeDisk(&cfg.homeArea);
  151.   makeSysName(tempName, "ctdlmsg.sys",  &cfg.msgArea);
  152.   if ((msgfl = fopen(tempName, R_W_ANY)) == NULL)
  153.     {
  154.     if (!attended)illegal("!System must be attended(ctdlmsg.sys) for creation!");
  155.     printf(" %s not found, creating new file. \n", tempName);
  156.     if ((msgfl = fopen(tempName, W_R_ANY)) == NULL)    illegal("?Can't create the message file!");
  157.     printf(" (Be sure to initialize it!)\n");
  158.  
  159.     }
  160.   makeSysName(tempName, "ctdllog.sys", &cfg.logArea);
  161.   /* open userlog file */
  162.   if ((logfl = fopen(tempName, R_W_ANY)) == NULL)
  163.     {
  164.     if (!attended)illegal("!System must be attended(ctdllog.sys) for creation!");
  165.     printf(" %s not found, creating new file. \n", tempName);
  166.     if ((logfl = fopen(tempName, W_R_ANY)) == NULL) illegal("?Can't create log file!");
  167.     printf(" (Be sure to initialize it!)\n");
  168.  
  169.     }
  170.   makeSysName(tempName, "ctdlroom.sys", &cfg.roomArea);
  171.   /* open room file */
  172.   if ((roomfl = fopen(tempName, R_W_ANY)) == NULL)
  173.     {
  174.     if (!attended)illegal("!System must be attended(ctdlroom.sys) for creation!");
  175.     printf(" %s not found, creating new file. \n", tempName);
  176.     if ((roomfl = fopen(tempName, W_R_ANY)) == NULL) illegal("?Can't create room file!");
  177.     printf(" (Be sure to initialize it!)\n");
  178.  
  179.     }
  180.   if (cfg.BoolFlags.netParticipant)
  181.     {
  182.     makeSysName(tempName, "ctdlnet.sys", &cfg.netArea);
  183.     if ((netfl = fopen(tempName, READ_ANY)) == NULL)
  184.       {
  185.       printf(" %s not found, creating new file.\n", tempName);
  186.       if ((netfl = fopen(tempName, WRITE_ANY)) == NULL)illegal("?Can't create the net file!");
  187.  
  188.       }
  189.  
  190.     }
  191.   CheckFloors();
  192.   if (attended || FirstInit)
  193.     {
  194.     char cx;
  195.     printf("\n Erase and initialize log, message and/or room files?");
  196.     cx = simpleGetch();
  197.     if (FirstInit || toUpper(cx)  == 'Y')
  198.       {
  199.       /* each of these has an additional go/no-go interrogation: */
  200.       msgZap  = zapMsgFile();
  201.       roomZap = zapRoomFile();
  202.       logZap  = zapLogFile();
  203.  
  204.       }
  205.  
  206.     }
  207.  
  208.   }
  209. /*
  210. * main()
  211. *
  212. * Main manager for confg.c.
  213. */
  214. int main(int, char **);
  215. int main(int argc, char **argv)
  216.   {
  217.   FILE *fBuf, *pwdfl;
  218.   char line[90], status, *strchr(), *g;
  219.   char onlyParams = FALSE, CleanCalllog;
  220.   char var[90];
  221.   int  arg;
  222.   int  i, offset = 1;
  223.   extern char *READ_TEXT;
  224.   int  SetVal;
  225.   if (argc > 1)
  226.     {
  227.     if (strCmpU(argv[1], "exists") == 0)
  228.       {
  229.       fBuf = fopen("exists", "w");
  230.       fprintf(fBuf, "I exist.");
  231.       fclose(fBuf);
  232.       exit(1);
  233.  
  234.       }
  235.  
  236.     }
  237.   cfg.paramVers = 11;
  238.   printf("%s Configurator (V%d.8)\n%s\n\n", VARIANT_NAME,
  239.   cfg.paramVers, COPYRIGHT);
  240.   if (access(LOCKFILE, 0) != -1)
  241.     {
  242.     char cx;
  243.     printf(
  244.     "You are apparently reconfiguring from within Citadel, which is a No No!\n"
  245.     "Do you wish to continue? ");
  246.     cx = simpleGetch();
  247.     if (toUpper(cx) != 'Y')
  248.     exit(7);
  249.     unlink(LOCKFILE);
  250.  
  251.     }
  252.   zero_struct(cfg);
  253.   for (i = 1;  i < argc; i++)
  254.     {
  255.     if (strCmpU(argv[i], "onlyParams") == SAMESTRING )
  256.       onlyParams = TRUE;
  257.     else if (strCmpU(argv[i], "FirstInit") == SAMESTRING)
  258.       FirstInit = TRUE;
  259.     else if (strCmpU(argv[i], "ReInit") == SAMESTRING)
  260.       ReInit = TRUE;
  261.     else if( argv[i][0] == '-' )
  262.       {
  263.       switch (argv[i][1])
  264.         {
  265.         case 'o':   /* Only Parameters */
  266.         case 'O':   onlyParams = TRUE; break;
  267.         case 'F':   /* First Initialization */
  268.         case 'I':
  269.         case 'f':
  270.         case 'i':   FirstInit = TRUE; break;
  271.         case 'r':   /* Re-Initialization */
  272.         case 'R':   ReInit = TRUE; break;
  273.         default:
  274.           fprintf(stderr,"Parameter Error, Assuming ReInit\n");
  275.           ReInit = TRUE;
  276.         };
  277.       }
  278.     else if (!sysArgs(argv[i]))
  279.       ReInit = TRUE;
  280.     }
  281.   cfg.weAre     = CONFIGUR;
  282.   if (!(SetVal = readSysTab(FALSE, FALSE)))
  283.     {
  284.     cfg.sysPassword[0] = 0;
  285.     cfg.MAXLOGTAB = 0;      /* Initialize, just in case   */
  286.     cfg.ConTimeOut = -1;  /* optional parameter */
  287.     if (onlyParams)
  288.       {
  289.       printf("'onlyParams' parameter ignored\n");
  290.       onlyParams = FALSE;
  291.  
  292.       }
  293.  
  294.     }
  295.   else
  296.     {
  297.     if (EventTab != NULL) free(EventTab);
  298.     i = cfg.BoolFlags.noChat;
  299.     zero_struct(cfg.BoolFlags);
  300.     cfg.BoolFlags.noChat = i;
  301.  
  302.     }
  303.   cfg.paramVers = 11;   /* yes, set it twice*   */
  304.   InitBuffers();        /* initializes message buffers */
  305.   initSysSpec();        /* Call implementation specific code  */
  306.   /* these are mostly optional param values */
  307.   cfg.SysopName[0]     = 0;
  308.   cfg.SysopArchive[0]  = 0;
  309.   strCpy(cfg.DomainDisplay, " _ %s");
  310.   cfg.InitColumns      = 40;
  311.   cfg.BoolFlags.IsDoor = FALSE;
  312.   cfg.BoolFlags.NetScanBad = FALSE;
  313.   cfg.EvNumber   = 0;
  314.   cfg.MailHub    = 0;
  315.   cfg.DomainHandlers   = 0;
  316.   KillList(&Serves);
  317.   CleanCalllog   = FALSE;
  318.   cfg.Audit     = 0;
  319.   cfg.BoolFlags.RouteMail  = TRUE;
  320.   cfg.BoolFlags.DL_Default = TRUE;
  321.   cfg.AnonMailLength   = 0;
  322.   cfg.LoginAttempts    = 0;
  323.   zero_array(cfg.DialPrefixes);
  324.   cfg.MailHub   = 0;
  325.   EventTab = NULL;
  326.   if ((fBuf = fopen("ctdlcnfg.sys", READ_TEXT)) == NULL)
  327.     {
  328.     /* ASCII mode   */
  329.     printf("?Can't find ctdlCnfg.sys!\n");
  330.     exit(1);
  331.  
  332.     }
  333.   while (fgets(line, 90, fBuf) != NULL)
  334.     {
  335.     if (line[0] != '#') continue;
  336.     if (sscanf(line, "%s %d ", var, &arg))
  337.       {
  338.       printf("%s", line);
  339.       if (NetParse(line, &offset, var, arg, SetVal))
  340.         {
  341.         continue;
  342.  
  343.         }
  344.       else if (strCmpU(var, "#CRYPTSEED" )    == SAMESTRING)
  345.         {
  346.         cfg.cryptSeed   = arg;
  347.  
  348.         }
  349.       else if (strCmpU(var, "#MESSAGEK"  )    == SAMESTRING)
  350.         {
  351.         cfg.maxMSector  = arg*(1024/MSG_SECT_SIZE);
  352.  
  353.         }
  354.       else if (strCmpU(var, "#LOGINOK"   )    == SAMESTRING)
  355.         {
  356.         cfg.BoolFlags.unlogLoginOk= arg;
  357.  
  358.         }
  359.       else if (strCmpU(var, "#ISDOOR"   )    == SAMESTRING)
  360.         {
  361.         cfg.BoolFlags.IsDoor = TRUE;
  362.  
  363.         }
  364.       else if (strCmpU(var, "#DoorPrivs")     == SAMESTRING)
  365.         {
  366.         cfg.BoolFlags.DoorDft     = arg;
  367.  
  368.         }
  369.       else if (strCmpU(var, "#FILE-PRIV-DEFAULT")     == SAMESTRING)
  370.         {
  371.         cfg.BoolFlags.DL_Default     = arg;
  372.  
  373.         }
  374.       else if (strCmpU(var, "#ENTEROK"   )    == SAMESTRING)
  375.         {
  376.         cfg.BoolFlags.unlogEnterOk= arg;
  377.  
  378.         }
  379.       else if (strCmpU(var, "#READOK"    )    == SAMESTRING)
  380.         {
  381.         cfg.BoolFlags.unlogReadOk = arg;
  382.  
  383.         }
  384.       else if (strCmpU(var, "#ROOMOK"    )    == SAMESTRING)
  385.         {
  386.         cfg.BoolFlags.nonAideRoomOk=arg;
  387.  
  388.         }
  389.       else if (strCmpU(var, "#ALLMAIL"   )    == SAMESTRING)
  390.         {
  391.         cfg.BoolFlags.noMail      = !arg;
  392.  
  393.         }
  394.       else if (strCmpU(var, "#UNLOGGED-WIDTH") == SAMESTRING)
  395.         {
  396.         cfg.InitColumns = arg;
  397.  
  398.         }
  399.       else if (strCmpU(var, "#LOGIN-ATTEMPTS") == SAMESTRING)
  400.         {
  401.         cfg.LoginAttempts = arg;
  402.  
  403.         }
  404.       else if (strCmpU(var, "#ANON-MAIL-LENGTH") == SAMESTRING)
  405.         {
  406.         cfg.AnonMailLength = arg;
  407.  
  408.         }
  409.       else if (strCmpU(var, "#CLEAN-CALLLOG") == SAMESTRING)
  410.         {
  411.         CleanCalllog = TRUE;
  412.  
  413.         }
  414.       else if (strCmpU(var, "#ANONYMOUS-SESSIONS") == SAMESTRING)
  415.         {
  416.         cfg.BoolFlags.AnonSessions = TRUE;
  417.  
  418.         }
  419.       else if (strCmpU(var, "#MIRRORMSG" )    == SAMESTRING)
  420.         {
  421.         cfg.BoolFlags.mirror = arg;
  422.  
  423.         }
  424.       else if (strCmpU(var, "#LOGSIZE"   )    == SAMESTRING)
  425.         {
  426.         if (SetVal)
  427.           {
  428.           if (cfg.MAXLOGTAB != arg)
  429.           illegal(
  430.           "LOGSIZE parameter does not equal old value!");
  431.  
  432.           }
  433.         else
  434.           {
  435.           cfg.MAXLOGTAB   = arg;
  436.           logTab = (LogTable *)
  437.           GetDynamic(sizeof(*logTab) * arg);
  438.  
  439.           }
  440.  
  441.         }
  442.       else if (strCmpU(var, "#MAXROOMS"  )    == SAMESTRING)
  443.         {
  444.         if (SetVal)
  445.           {
  446.           if (MAXROOMS != arg)
  447.           illegal(
  448.           "MAXROOMS parameter does not equal old value!");
  449.  
  450.           }
  451.         else
  452.           {
  453.           MAXROOMS = arg;
  454.           if (MAXROOMS <= 3)
  455.           illegal("MAXROOMS must be greater than 3!");
  456.           roomTab = (rTable *)
  457.           GetDynamic(MAXROOMS * sizeof *roomTab);
  458.  
  459.           }
  460.  
  461.         }
  462.       else if (strCmpU(var, "#MSG-SLOTS" )    == SAMESTRING)
  463.         {
  464.         if (SetVal)
  465.           {
  466.           if (MSGSPERRM != arg)
  467.           illegal(
  468.           "MSGSPERRM parameter does not equal old value!");
  469.  
  470.           }
  471.         else
  472.           {
  473.           MSGSPERRM = arg;
  474.  
  475.           }
  476.  
  477.         }
  478.       else if (strCmpU(var, "#MAIL-SLOTS")    == SAMESTRING)
  479.         {
  480.         if (SetVal)
  481.           {
  482.           if (MAILSLOTS != arg)
  483.           illegal(
  484.           "MAILSLOTS parameter does not equal old value!");
  485.  
  486.           }
  487.         else
  488.           {
  489.           MAILSLOTS = arg;
  490.  
  491.           }
  492.  
  493.         }
  494.       else if (strCmpU(var, "#AIDESEEALL")    == SAMESTRING)
  495.         {
  496.         cfg.BoolFlags.aideSeeAll = arg;
  497.  
  498.         }
  499.       else if (strCmpU(var, "#CONSOLE-TIMEOUT")    == SAMESTRING)
  500.         {
  501.         cfg.ConTimeOut = arg;
  502.  
  503.         }
  504.       else if (strCmpU(var, "#SYSBAUD"   )    == SAMESTRING)
  505.         {
  506.         cfg.sysBaud   = arg;
  507.         if (arg > 8 || arg < 0)
  508.           {
  509.           illegal(BAUDS);
  510.  
  511.           }
  512.  
  513.         }
  514.       else if (strCmpU(var, "#event"    ) == SAMESTRING)
  515.         {
  516.         offset = EatEvent(line, offset);
  517.  
  518.         }
  519.       else if (strCmpU(var, "#nodeTitle") == SAMESTRING)
  520.         {
  521.         readString(line, &cfg.codeBuf[offset], TRUE);
  522.         cfg.nodeTitle = offset;
  523.         while (cfg.codeBuf[offset])
  524.         offset++;
  525.         offset++;
  526.  
  527.         }
  528.       else if (strCmpU(var, "#sysPassword") == SAMESTRING)
  529.         {
  530.         readString(line, cfg.sysPassword, FALSE);
  531.         if ((pwdfl = fopen(cfg.sysPassword, READ_TEXT)) == NULL)
  532.           {
  533.           printf("\nNo system password file found\n");
  534.           cfg.sysPassword[0] = 0;
  535.  
  536.           }
  537.         else
  538.           {
  539.           fgets(cfg.sysPassword, 199, pwdfl);
  540.           /*  cfg.sysPassword[strLen(cfg.sysPassword) - 1] = 0;*/
  541.           while ((g = strchr(cfg.sysPassword, '\n')) != NULL)
  542.           *g = 0;
  543.           if (strLen(cfg.sysPassword) < 15)
  544.             {
  545.             printf("\nSystem password is too short -- ignored\n");
  546.             cfg.sysPassword[0] = 0;
  547.  
  548.             }
  549.           fclose(pwdfl);
  550.  
  551.           }
  552.  
  553.         }
  554.       else if (strCmpU(var, "#sysopName") == SAMESTRING)
  555.         {
  556.         readString(line, msgBuf.mbtext, FALSE);
  557.         if (strLen(msgBuf.mbtext) > 19)
  558.         illegal("SysopName too long; must be less than 20");
  559.         strCpy(cfg.SysopName, msgBuf.mbtext);
  560.  
  561.         }
  562.       else if (strCmpU(var, "#SYSOP-ARCHIVE") == SAMESTRING)
  563.         {
  564.         readString(line, msgBuf.mbtext, FALSE);
  565.         if (strLen(msgBuf.mbtext) > sizeof cfg.SysopArchive)
  566.           {
  567.           sprintf(msgBuf.mbtext, "SysopName too long; must be less than %d", sizeof cfg.SysopArchive);
  568.           illegal(msgBuf.mbtext);
  569.  
  570.           }
  571.         strCpy(cfg.SysopArchive, msgBuf.mbtext);
  572.  
  573.         }
  574.       else if (strCmpU(var, "#baseRoom") == SAMESTRING)
  575.         {
  576.         readString(line, &cfg.codeBuf[offset], TRUE);
  577.         if (strLen(&cfg.codeBuf[offset]) > 19)
  578.         illegal("baseRoom too long; must be less than 20");
  579.         cfg.bRoom = offset;
  580.         baseRoom = &cfg.codeBuf[offset];
  581.         while (cfg.codeBuf[offset])
  582.         offset++;
  583.         offset++;
  584.  
  585.         }
  586.       else if (strCmpU(var, "#MainFloor") == SAMESTRING)
  587.         {
  588.         readString(line, &cfg.codeBuf[offset], TRUE);
  589.         if (strLen(&cfg.codeBuf[offset]) > 19)
  590.         illegal("#MainFloor too long; must be less than 20");
  591.         cfg.MainFloor = offset;
  592.         while (cfg.codeBuf[offset])
  593.         offset++;
  594.         offset++;
  595.  
  596.         }
  597.       else if (strCmpU(var, "#alldone") == SAMESTRING)
  598.         {
  599.         break;
  600.  
  601.         }
  602.       else
  603.         {
  604.         offset = sysSpecs(line, offset, &status, fBuf);
  605.         if (!status)
  606.         printf("? -- no variable '%s' known! -- ignored.\n", var);
  607.  
  608.         }
  609.  
  610.       }
  611.  
  612.     }
  613.   for (i = 0; i <= B_7; i++)
  614.   if (cfg.DialPrefixes[i] == 0)
  615.     {
  616.     cfg.DialPrefixes[i] = DefaultPrefix;
  617.  
  618.     }
  619.   if (cfg.Audit == 1)
  620.   if (CleanCalllog) cfg.Audit = 2;
  621.   initLogBuf(&logBuf);
  622.   initRoomBuf(&roomBuf);
  623.   initNetBuf(&netBuf);
  624.   if (!SysDepIntegrity(&offset))  exit(100);
  625.   RunList(&Events, EvIsDoor);
  626.   printf("offset=%d\n", offset);
  627.   if (offset < MAXCODE)
  628.     {
  629.     if (!onlyParams) init(!ReInit);
  630.     else
  631.       {
  632.       CheckFloors();
  633.       if (cfg.BoolFlags.netParticipant)
  634.       CheckNet();
  635.  
  636.       }
  637.     wrapup(onlyParams);
  638.  
  639.     }
  640.   else
  641.     {
  642.     illegal(
  643.     "\7codeBuf[] overflow! Recompile with larger MAXCODE or reduce ctdlCnfg.sys\7"
  644.     );
  645.  
  646.     }
  647.   return 0;
  648.  
  649.   }
  650. /*
  651. * readString()
  652. *
  653. * This function reads a '#<id> "<value>"  since scanf can't.
  654. */
  655. void readString(char *source, char *destination, char doProc)
  656.   {
  657.   char string[300], last = 0;
  658.   int  i, j;
  659.   for (i = 0; source[i] != '"' && source[i]; i++)
  660.   ;
  661.   if (!source[i])
  662.     {
  663.     sPrintf(string, "Couldn't find beginning \" in -%s-", source);
  664.     illegal(string);
  665.  
  666.     }
  667.   for (j = 0, i++; source[i] &&
  668.   (source[i] != '"' || (doProc && last == '\\'));
  669.   i++, j++)
  670.     {
  671.     string[j] = source[i];
  672.     last = source[i];
  673.  
  674.     }
  675.   if (!source[i])
  676.     {
  677.     sPrintf(string, "Couldn't find ending \" in -%s-", source);
  678.     illegal(string);
  679.  
  680.     }
  681.   string[j] = '\0';
  682.   strCpy(destination, string);
  683.   if (doProc) xlatfmt(destination);
  684.  
  685.   }
  686. /*
  687. * isoctal() * xlatfmt()
  688. *
  689. * contributed by Dale Schumacher, allow embedding of formatting info a la'
  690. * "C" style: \n, \t, etc....
  691. */
  692. char isoctal( int c )
  693.   {
  694.   return  (char)(( c >= '0' ) && ( c <= '7' ));
  695.  
  696.   }
  697. void xlatfmt( char *s )
  698.   {
  699.   register char *p, *q;
  700.   register int i;
  701.   for( p=q=s; *q; ++q )
  702.     {
  703.     if ( *q == '\\' )
  704.     switch( *++q )
  705.       {
  706.       case 'n' :
  707.       *p++ = '\n';
  708.       break;
  709.       case 't' :
  710.       *p++ = '\t';
  711.       break;
  712.       case 'r' :
  713.       *p++ = '\r';
  714.       break;
  715.       case 'f' :
  716.       *p++ = '\f';
  717.       break;
  718.       default :
  719.       if ( isoctal( *q ))
  720.         {
  721.         i = (( *q++ ) - '0' );
  722.         if ( isoctal( *q ))
  723.           {
  724.           i <<= 3;
  725.           i += (( *q++ ) - '0' );
  726.           if ( isoctal( *q ))
  727.             {
  728.             i <<= 3;
  729.             i += (*q -'0');
  730.  
  731.             }
  732.           else
  733.           --q;
  734.  
  735.           }
  736.         else
  737.         --q;
  738.         *p++ = 0xFF & ((char) i);
  739.  
  740.         }
  741.       else
  742.       *p++ = *q;
  743.       break;
  744.  
  745.       }
  746.     else
  747.     *p++ = *q;
  748.  
  749.     }
  750.   *p = '\0';
  751.  
  752.   }
  753. /*
  754. * illegal()
  755. *
  756. * This will print out configure error message and aborts.
  757. */
  758. void illegal(char *errorstring)
  759.   {
  760.   printf("\007\nERROR IN CONFIGURATION:\n%s\nABORTING", errorstring);
  761.   exit(100);
  762.  
  763.   }
  764. /*
  765. * dGetWord()
  766. *
  767. * This fetches one word from current message, off disk, returns TRUE if more
  768. * words follow, else FALSE.
  769. */
  770. char dGetWord(char *dest, int lim)
  771.   {
  772.   char c;
  773.   --lim;      /* play it safe */
  774.   /* pick up any leading blanks: */
  775.   for (c = getMsgChar();   c == ' '  &&  c && lim;   c = getMsgChar())
  776.     {
  777.     if (lim)
  778.       {
  779.       *dest++ = c;   lim--;
  780.  
  781.       }
  782.  
  783.     }
  784.   /* step through word: */
  785.   for (   ;  c != ' ' && c && lim;   c = getMsgChar())
  786.     {
  787.     if (lim)
  788.       {
  789.       *dest++ = c;   lim--;
  790.  
  791.       }
  792.  
  793.     }
  794.   /* trailing blanks: */
  795.   for (   ;   c == ' ' && c && lim;   c = getMsgChar())
  796.     {
  797.     if (lim)
  798.       {
  799.       *dest++ = c;   lim--;
  800.  
  801.       }
  802.  
  803.     }
  804.   if (c)  unGetMsgChar(c);    /* took one too many    */
  805.   *dest = '\0';        /* tie off string       */
  806.   return  c;
  807.  
  808.   }
  809. /*
  810. * msgInit()
  811. *
  812. * This sets up lowId, highId, cfg.catSector and cfg.catChar, by scanning over
  813. * ctdlmsg.sys.
  814. */
  815. void msgInit()
  816.   {
  817.   MSG_NUMBER first, here;
  818.   CheckPoint Cpt;
  819.   FILE *fd;
  820.   extern struct mBuf mFile1;
  821.   if ((fd = fopen(CHECKPT, READ_ANY)) != NULL)
  822.     {
  823.     fread(&Cpt, sizeof Cpt, 1, fd);
  824.     fclose(fd);
  825.     if (findMessage(Cpt.loc, Cpt.ltnewest, TRUE))
  826.       {
  827.       do
  828.         {
  829.         printf("message# %s\r", msgBuf.mbId);
  830.         while (dGetWord(msgBuf.mbtext, MAXTEXT));
  831.         cfg.catSector   = mFile1.thisSector;
  832.         cfg.catChar     = mFile1.thisChar;
  833.         cfg.newest      = atol(msgBuf.mbId);
  834.         getMessage(getMsgChar, FALSE, FALSE, TRUE);
  835.  
  836.         }
  837.       while (atol(msgBuf.mbId) >= Cpt.ltnewest);
  838.       cfg.oldest = atol(msgBuf.mbId);
  839.       printf("\n\noldest=%lu\n", cfg.oldest);
  840.       printf("newest=%lu\n", cfg.newest);
  841.       return;
  842.  
  843.       }
  844.  
  845.     }
  846.   startAt(msgfl, &mFile1, 0, 0);
  847.   getMessage(getMsgChar, FALSE, FALSE, TRUE);
  848.   /* get the ID# */
  849.   first = atol(msgBuf.mbId);
  850.   printf("message# %lu\n", first);
  851.   cfg.newest = cfg.oldest = first;
  852.   cfg.catSector   = mFile1.thisSector;
  853.   cfg.catChar     = mFile1.thisChar;
  854.   for (getMessage(getMsgChar, FALSE, FALSE, TRUE);
  855.   here = atol(msgBuf.mbId), here != first;
  856.   getMessage(getMsgChar, FALSE, FALSE, TRUE))
  857.     {
  858.     printf("message# %lu\r", here);
  859.     if (strCmpU("Mail", msgBuf.mbroom) == 0) mailCount++;
  860.     /* find highest and lowest message IDs: */
  861.     if (here < cfg.oldest && here != 0l)
  862.       {
  863.       cfg.oldest = here;
  864.  
  865.       }
  866.     if (here > cfg.newest)
  867.       {
  868.       cfg.newest = here;
  869.       /* read rest of message in and remember where it ends,  */
  870.       /* in case it turns out to be the last message    */
  871.       /* in which case, that's where to start writing next message*/
  872.       while (dGetWord(msgBuf.mbtext, MAXTEXT));
  873.       cfg.catSector   = mFile1.thisSector;
  874.       cfg.catChar     = mFile1.thisChar;
  875.  
  876.       }
  877.  
  878.     }
  879.   printf("\n\noldest=%lu\n", cfg.oldest);
  880.   printf("newest=%lu\n", cfg.newest);
  881.  
  882.   }
  883. /*
  884. * zapMsgFile()
  885. *
  886. * This function initializes ctdlmsg.sys.
  887. */
  888. char zapMsgFile()
  889.   {
  890.   extern char *W_R_ANY;
  891.   char cx, fn[80];
  892.   if (!FirstInit)
  893.     {
  894.     printf("\nDestroy all current messages? ");
  895.     cx = simpleGetch();
  896.     if (toUpper(cx) != 'Y')   return FALSE;
  897.  
  898.     }
  899.   if (cfg.BoolFlags.mirror) printf("Creating primary message file.\n");
  900.   if( realZap() )
  901.     {
  902.     if (cfg.BoolFlags.mirror)
  903.       {
  904.       fclose(msgfl);
  905.       makeSysName(fn, "ctdlmsg.sys", &cfg.msg2Area);
  906.       if ((msgfl = fopen(fn, W_R_ANY)) == NULL)
  907.       illegal("?Can't create the secondary message file!");
  908.       printf("Creating secondary message file.\n");
  909.       realZap();
  910.       };
  911.     };
  912.   return TRUE;
  913.  
  914.   }
  915. /*
  916. * realZap()
  917. *
  918. * This does the work of zapMsgFile.
  919. */
  920. char realZap()
  921.   {
  922.   int   i;
  923.   unsigned long sect;
  924.   /* put null message in first sector... */
  925.   sectBuf[0]  = 0xFF; /*   \        */
  926.   sectBuf[1]  =  '1'; /*    >  Message ID "1" MS-DOS style  */
  927.   sectBuf[2]  = '\0'; /*   /        */
  928.   sectBuf[3]  =  'M'; /*   \    Null messsage        */
  929.   sectBuf[4]  = '\0'; /*   /        */
  930.   cfg.newest = cfg.oldest = 1l;
  931.   cfg.catSector   = 0;
  932.   cfg.catChar     = 5;
  933.   for (i=5;  i<MSG_SECT_SIZE;  i++) sectBuf[i] = 0;
  934.   crypte(sectBuf, MSG_SECT_SIZE, 0);       /* encrypt      */
  935.   if (fwrite(sectBuf, MSG_SECT_SIZE, 1, msgfl) != 1)
  936.     {
  937.     printf("zapMsgFil: write failed\n");
  938.     return FALSE;
  939.     }
  940.   crypte(sectBuf, MSG_SECT_SIZE, 0);       /* decrypt      */
  941.   sectBuf[0] = 0;
  942.   crypte(sectBuf, MSG_SECT_SIZE, 0);       /* encrypt      */
  943.   printf("\n%d sectors to be cleared\n", cfg.maxMSector);
  944.   for (sect = 1l;  sect < cfg.maxMSector;  sect++)
  945.     {
  946.     printf("%07.7lu\r", sect);
  947.     if (fwrite(sectBuf, MSG_SECT_SIZE, 1, msgfl) != 1)
  948.       {
  949.       printf("zapMsgFil: write failed\n");
  950.       return FALSE;
  951.       }
  952.  
  953.     }
  954.   Zap_Nodes_Message_Index();               /* zap last netted message */
  955.   crypte(sectBuf, MSG_SECT_SIZE, 0);       /* decrypt      */
  956.   return TRUE;
  957.  
  958.   }
  959. /*
  960. * indexRooms()
  961. *
  962. * This will build a RAM index to CTDLROOM.SYS, displays stats.
  963. */
  964. void indexRooms()
  965.   {
  966.   int  goodRoom, m, roomCount, slot, WriteIt;
  967.   zero_struct(roomBuf.rbflags);
  968.   zero_struct(roomBuf.rbArea);
  969.   roomBuf.rbgen = 0;
  970.   roomBuf.rbname[0] = 0;
  971.   roomBuf.rbShareType = 0;
  972.   for (m = 0; m < MSGSPERRM; m++)
  973.     {
  974.     roomBuf.msg[m].rbmsgNo = 0l;
  975.     roomBuf.msg[m].rbmsgLoc = 0;
  976.  
  977.     }
  978.   strCpy(roomBuf.rbname, "Mail");
  979.   roomBuf.rbflags.PUBLIC =
  980.   roomBuf.rbflags.PERMROOM =
  981.   roomBuf.rbflags.INUSE = TRUE;
  982.   putRoom(MAILROOM);
  983.   roomCount = 0;
  984.   for (slot = 0;  slot < MAXROOMS;  slot++)
  985.     {
  986.     getRoom(slot);
  987.     printf("Checking room #%3d: ", slot);
  988.     WriteIt = FALSE;
  989.     if (roomBuf.rbflags.INUSE == 1)
  990.       {
  991.       WriteIt = TRUE;
  992.       roomBuf.rbflags.INUSE = 0;    /* clear "inUse" flag */
  993.       if (roomBuf.rbFlIndex >= (int) FloorSize)
  994.       roomBuf.rbFlIndex = 0;
  995.       for (m = 0, goodRoom = FALSE; m < MSGSPERRM && !goodRoom; m++)
  996.         {
  997.         if (roomBuf.msg[m].rbmsgNo > cfg.oldest)
  998.           {
  999.           goodRoom    = TRUE;
  1000.  
  1001.           }
  1002.  
  1003.         }
  1004.       if (goodRoom   || roomBuf.rbflags.PERMROOM == 1)
  1005.         {
  1006.         roomBuf.rbflags.INUSE = 1;
  1007.  
  1008.         }
  1009.       if (roomBuf.rbflags.INUSE == 1)
  1010.         {
  1011.         if (slot == 0)         /* Ugly kludge */
  1012.         strCpy(roomBuf.rbname, baseRoom);
  1013.         roomCount++;
  1014.  
  1015.         }
  1016.       else
  1017.         {
  1018.         zero_struct(roomBuf.rbflags);
  1019.  
  1020.         }
  1021.  
  1022.       }
  1023.     printf("%-20s\r",
  1024.     (roomBuf.rbflags.INUSE == 1) ? roomBuf.rbname : "<not in use>");
  1025.     if (WriteIt)
  1026.       {
  1027.       if (roomBuf.rbflags.INUSE && roomBuf.rbflags.SHARED)
  1028.       roomTab[slot].rtlastNet = findHighestNative();
  1029.       else
  1030.       roomTab[slot].rtlastNet = 0l;
  1031.       noteRoom();
  1032.       putRoom(slot);
  1033.  
  1034.       }
  1035.  
  1036.     }
  1037.   printf("\n %d of %d rooms in use\n", roomCount, MAXROOMS);
  1038.  
  1039.   }
  1040. /*
  1041. * findHighestNative()
  1042. *
  1043. * This finds the highest native message in a room.
  1044. */
  1045. MSG_NUMBER findHighestNative()
  1046.   {
  1047.   int rover;
  1048.   MSG_NUMBER ourHighest;
  1049.   theMessages *temp;
  1050.   temp = (theMessages *) GetDynamic(MSG_BULK);
  1051.   copy_ptr(roomBuf.msg, temp, MSGSPERRM);
  1052.   qsort(temp, MSGSPERRM, sizeof temp[0], msgSort);
  1053.   ourHighest = 0l;
  1054.   for (rover = 0; rover < MSGSPERRM; rover++)
  1055.     {
  1056.     if (temp[rover].rbmsgNo != 0l &&
  1057.     temp[rover].rbmsgNo >= cfg.oldest &&
  1058.     temp[rover].rbmsgNo <= cfg.newest &&
  1059.     cfindMessage(temp[rover].rbmsgLoc, temp[rover].rbmsgNo))
  1060.       {
  1061.       if (strCmpU(msgBuf.mbaddr, R_SH_MARK) == SAMESTRING ||
  1062.       strCmpU(msgBuf.mbaddr, NON_LOC_NET) == SAMESTRING)
  1063.         {
  1064.         ourHighest = temp[rover].rbmsgNo;
  1065.         break;
  1066.  
  1067.         }
  1068.  
  1069.       }
  1070.  
  1071.     }
  1072.   free(temp);
  1073.   return ourHighest;
  1074.  
  1075.   }
  1076. /*
  1077. * msgSort()
  1078. *
  1079. * This function sorts messages by their native msg id.
  1080. */
  1081. int msgSort(theMessages *s1, theMessages *s2)
  1082.   {
  1083.   if (s1->rbmsgNo < s2->rbmsgNo) return 1;
  1084.   if (s1->rbmsgNo > s2->rbmsgNo) return -1;
  1085.   return 0;
  1086.  
  1087.   }
  1088. /*
  1089. * noteRoom()
  1090. *
  1091. * This function will enter room into RAM index array.
  1092. */
  1093. void noteRoom()
  1094.   {
  1095.   int   i;
  1096.   MSG_NUMBER last;
  1097.   last = 0l;
  1098.   for (i = 0;  i < MSGSPERRM;  i++)
  1099.     {
  1100.     if (roomBuf.msg[i].rbmsgNo > cfg.newest)
  1101.       {
  1102.       roomBuf.msg[i].rbmsgNo = 0l;
  1103.  
  1104.       }
  1105.     if (roomBuf.msg[i].rbmsgNo > last)
  1106.       {
  1107.       last = roomBuf.msg[i].rbmsgNo;
  1108.  
  1109.       }
  1110.  
  1111.     }
  1112.   roomTab[thisRoom].rtlastMessage = last     ;
  1113.   roomTab[thisRoom].rtShareType   = roomBuf.rbShareType;
  1114.   strCpy(roomTab[thisRoom].rtname, roomBuf.rbname) ;
  1115.   roomTab[thisRoom].rtgen     = roomBuf.rbgen  ;
  1116.   roomTab[thisRoom].rtFlIndex = roomBuf.rbFlIndex;
  1117.   copy_struct(roomBuf.rbflags, roomTab[thisRoom].rtflags);
  1118.  
  1119.   }
  1120. /*
  1121. * zapRoomFile()
  1122. *
  1123. * This function erases and re-initializes CTDLROOM.SYS.
  1124. */
  1125. char zapRoomFile()
  1126.   {
  1127.   int i;
  1128.   char cx;
  1129.   if (!FirstInit)
  1130.     {
  1131.     printf("\nWipe room file? ");
  1132.     cx = simpleGetch();
  1133.     if (toUpper(cx) != 'Y') return FALSE;
  1134.     printf("\n");
  1135.  
  1136.     }
  1137.   zero_struct(roomBuf.rbflags);
  1138.   roomBuf.rbgen     = 0;
  1139.   roomBuf.rbname[0] = 0;   /* unnecessary -- but I like it...  */
  1140.   for (i = 0;  i < MSGSPERRM;  i++)
  1141.     {
  1142.     roomBuf.msg[i].rbmsgNo =  0l;
  1143.     roomBuf.msg[i].rbmsgLoc = 0 ;
  1144.  
  1145.     }
  1146.   printf("maxrooms=%d\n", MAXROOMS);
  1147.   for (thisRoom = 0;  thisRoom < MAXROOMS;  thisRoom++)
  1148.     {
  1149.     printf("clearing room %d\r", thisRoom);
  1150.     RoomSys(thisRoom);
  1151.     putRoom(thisRoom);
  1152.     noteRoom();
  1153.  
  1154.     }
  1155.   printf("\n");
  1156.   /* Lobby> always exists -- guarantees us a place to stand! */
  1157.   thisRoom      = 0      ;
  1158.   strCpy(roomBuf.rbname, baseRoom)    ;
  1159.   roomBuf.rbflags.PERMROOM = TRUE;
  1160.   roomBuf.rbflags.PUBLIC   = TRUE;
  1161.   roomBuf.rbflags.INUSE    = TRUE;
  1162.   RoomSys(0);
  1163.   putRoom(LOBBY);
  1164.   noteRoom();
  1165.   /* Mail> is also permanent...       */
  1166.   thisRoom      = MAILROOM      ;
  1167.   strCpy(roomBuf.rbname, "Mail")      ;
  1168.   RoomSys(1);
  1169.   /* Don't bother to copy flags, they remain the same (right?)    */
  1170.   putRoom(MAILROOM);
  1171.   noteRoom();
  1172.   /* Aide> also...    */
  1173.   thisRoom      = AIDEROOM      ;
  1174.   strCpy(roomBuf.rbname, "Aide")      ;
  1175.   roomBuf.rbflags.PERMROOM = TRUE;
  1176.   roomBuf.rbflags.PUBLIC   = FALSE;
  1177.   roomBuf.rbflags.INUSE    = TRUE;
  1178.   RoomSys(2);
  1179.   putRoom(AIDEROOM);
  1180.   noteRoom();
  1181.   return TRUE;
  1182.  
  1183.   }
  1184. /*
  1185. * logInit()
  1186. *
  1187. * This function indexes ctdllog.sys.
  1188. */
  1189. void logInit()
  1190.   {
  1191.   int i;
  1192.   int count = 0;
  1193.   #ifdef IS_RIGHT
  1194.   if (rewind(logfl) != 0) illegal("Rewinding logfl failed!");
  1195.   #else
  1196.   rewind(logfl);
  1197.   #endif
  1198.   /* clear logTab */
  1199.   for (i = 0; i < cfg.MAXLOGTAB; i++) logTab[i].ltnewest = 0l;
  1200.   /* load logTab: */
  1201.   for (thisLog = 0;  thisLog < cfg.MAXLOGTAB;  thisLog++)
  1202.     {
  1203.     printf("log #%04d", thisLog);
  1204.     getLog(&logBuf, thisLog);
  1205.     /* count valid entries:      */
  1206.     if (logBuf.lbflags.L_INUSE == 1)
  1207.       {
  1208.       count++;
  1209.       printf("   %20s", logBuf.lbname);
  1210.  
  1211.       }
  1212.     else printf("   <not in use>       ");
  1213.     printf("\r");
  1214.     /* copy relevant info into index:   */
  1215.     logTab[thisLog].ltnewest = logBuf.lbvisit[0];
  1216.     logTab[thisLog].ltlogSlot= thisLog;
  1217.     if (logBuf.lbflags.L_INUSE == 1)
  1218.       {
  1219.       logTab[thisLog].ltnmhash = hash(logBuf.lbname);
  1220.       logTab[thisLog].ltpwhash = hash(logBuf.lbpw  );
  1221.       logTab[thisLog].ltpermanent = logBuf.lbflags.PERMANENT;
  1222.  
  1223.       }
  1224.     else
  1225.       {
  1226.       logTab[thisLog].ltnmhash = 0;
  1227.       logTab[thisLog].ltpwhash = 0;
  1228.  
  1229.       }
  1230.  
  1231.     }
  1232.   printf("\n logInit--%d valid log entries\n", count);
  1233.   printf("sort Log...\n");
  1234.   qsort(logTab, cfg.MAXLOGTAB, cfg.sizeLTentry, logSort);
  1235.  
  1236.   }
  1237. /*
  1238. * logSort()
  1239. *
  1240. * This function Sorts 2 entries in logTab.
  1241. */
  1242. int logSort(LogTable *s1, LogTable *s2)
  1243.   {
  1244.   if (s1->ltnmhash == 0 && s2->ltnmhash == 0)
  1245.   return 0;
  1246.   if (s1->ltnmhash == 0 && s2->ltnmhash != 0)
  1247.   return 1;
  1248.   if (s1->ltnmhash != 0 && s2->ltnmhash == 0)
  1249.   return -1;
  1250.   if (s1->ltnewest < s2->ltnewest)
  1251.   return 1;
  1252.   if (s1->ltnewest > s2->ltnewest)
  1253.   return -1;
  1254.   return 0;
  1255.  
  1256.   }
  1257. /*
  1258. * noteLog()
  1259. *
  1260. * This notes a logTab entry in RAM buffer in master index.
  1261. */
  1262. void noteLog()
  1263.   {
  1264.   int i, slot;
  1265.   /* figure out who it belongs between: */
  1266.   for (i = 0;  logTab[i].ltnewest > logBuf.lbvisit[0];  i++);
  1267.   /* note location and open it up:  */
  1268.   slot = i;
  1269.   slideLTab(slot, cfg.MAXLOGTAB-1);
  1270.   /* insert new record */
  1271.   logTab[slot].ltnewest       = logBuf.lbvisit[0]  ;
  1272.   logTab[slot].ltlogSlot      = thisLog     ;
  1273.   logTab[slot].ltpwhash       = hash(logBuf.lbpw)  ;
  1274.   logTab[slot].ltnmhash       = hash(logBuf.lbname);
  1275.  
  1276.   }
  1277. /*
  1278. * slideLTab()
  1279. *
  1280. * This function slides bottom N slots in logTab down.  For sorting.
  1281. */
  1282. void slideLTab(int slot, int last)
  1283.   {
  1284.   int i;
  1285.   /* open slot up: (movmem isn't guaranteed on overlaps) */
  1286.   for (i = last - 1;  i >= slot;  i--)
  1287.     {
  1288.     movmem(&logTab[i], &logTab[i + 1], cfg.sizeLTentry);
  1289.  
  1290.     }
  1291.  
  1292.   }
  1293. /*
  1294. * wrapup()
  1295. *
  1296. * This finishes up and writes ctdlTabl.sys out, finally.
  1297. */
  1298. void wrapup(char onlyParams)
  1299.   {
  1300.   printf("\ncreating ctdlTabl.sys table\n");
  1301.   if (!onlyParams)
  1302.     {
  1303.     if (!msgZap)  msgInit();
  1304.     if (!roomZap) indexRooms();
  1305.     cfg.weAre = CITADEL;
  1306.     if (!logZap)  logInit();
  1307.     netInit();
  1308.     if (mailCount)
  1309.     printf("%d of the messages were Mail\n", mailCount);
  1310.  
  1311.     }
  1312.   EventTab = (EVENT *) GetDynamic(cfg.EvNumber * sizeof *EventTab);
  1313.   if (!FinalSystemCheck(onlyParams)) exit(2);
  1314.   if (!onlyParams)
  1315.     {
  1316.     if (cfg.BoolFlags.netParticipant)
  1317.     fclose(netfl);
  1318.     fclose(roomfl);
  1319.     fclose(msgfl);
  1320.     fclose(logfl);
  1321.  
  1322.     }
  1323.   RunList(&Events, EventWrite); /* because we keep this in a linked list */
  1324.   printf("writeSysTab = %d\n", writeSysTab());
  1325.  
  1326.   }
  1327. /*
  1328. * zapLogFile()
  1329. *
  1330. * This erases & re-initializes ctdllog.sys.
  1331. */
  1332. char zapLogFile()
  1333.   {
  1334.   int  i;
  1335.   char cx;
  1336.   if (!FirstInit)
  1337.     {
  1338.     printf("\nWipe out log file? ");
  1339.     cx = simpleGetch();
  1340.     if (toUpper(cx) != 'Y')   return FALSE;
  1341.     printf("\n");
  1342.  
  1343.     }
  1344.   /* clear RAM buffer out:      */
  1345.   logBuf.lbflags.L_INUSE = FALSE;
  1346.   for (i = 0;  i < MAILSLOTS;  i++)
  1347.     {
  1348.     logBuf.lbMail[i].rbmsgLoc = 0l;
  1349.     logBuf.lbMail[i].rbmsgNo  = 0l;
  1350.  
  1351.     }
  1352.   for (i = 0;  i < NAMESIZE;  i++)
  1353.     {
  1354.     logBuf.lbname[i] = 0;
  1355.     logBuf.lbpw[i]   = 0;
  1356.  
  1357.     }
  1358.   /* write empty buffer all over file;  */
  1359.   for (i = 0; i < cfg.MAXLOGTAB;  i++)
  1360.     {
  1361.     printf("Clearing log #%d\r", i);
  1362.     putLog(&logBuf, i);
  1363.     logTab[i].ltnewest = logBuf.lbvisit[0];
  1364.     logTab[i].ltlogSlot= i;
  1365.     logTab[i].ltnmhash = hash(logBuf.lbname);
  1366.     logTab[i].ltpwhash = hash(logBuf.lbpw  );
  1367.  
  1368.     }
  1369.   return TRUE;
  1370.  
  1371.   }
  1372. /*
  1373. * netInit()
  1374. *
  1375. * This will Initialize RAM index for Ctdlnet.sys.
  1376. */
  1377. void netInit()
  1378.   {
  1379.   label temp;
  1380.   int i = 0;
  1381.   long length;
  1382.   if (!cfg.BoolFlags.netParticipant) return;
  1383.   totalBytes(&length, netfl);
  1384.   cfg.netSize = (int) (length / NB_TOTAL_SIZE);
  1385.   if (cfg.netSize)
  1386.   netTab = (NetTable *) GetDynamic(sizeof (*netTab) * cfg.netSize);
  1387.   else
  1388.   netTab = NULL;
  1389.   while (i < cfg.netSize)
  1390.     {
  1391.     getNet(i, &netBuf);
  1392.     netTab[i].netTRooms = (SharedRoom *)
  1393.     GetDynamic(sizeof (*netBuf.netRooms) * SHARED_ROOMS);
  1394.     normId(netBuf.netId, temp);
  1395.     netTab[i].ntnmhash = hash(netBuf.netName);
  1396.     netTab[i].ntidhash = hash(temp);
  1397.     strCpy(netTab[i].ntShort, netBuf.nbShort);
  1398.     copy_struct(netBuf.nbflags, netTab[i].ntflags);
  1399.     movmem(netBuf.netRooms, netTab[i].netTRooms,
  1400.     sizeof *netBuf.netRooms * SHARED_ROOMS);
  1401.     netTab[i].ntMemberNets = netBuf.MemberNets;
  1402.     printf("System %3d. %s\n", i,
  1403.     (netBuf.nbflags.in_use) ? netBuf.netName : "<not in use>");
  1404.     i++;
  1405.  
  1406.     }
  1407.   if (cfg.MailHub != 0)
  1408.     {
  1409.     if (searchNameNet(cfg.MailHub + cfg.codeBuf, &netBuf) == -1)
  1410.     illegal("Your #MailHub node was not found in your CtdlNet.Sys.");
  1411.     if (netBuf.nbRoute != -1 &&
  1412.     netTab[netBuf.nbRoute].ntGen == netBuf.nbRouteGen)
  1413.     illegal("You must have a direct connect to your #MailHub.");
  1414.  
  1415.     }
  1416.  
  1417.   }
  1418. /*
  1419. * strCmpU()
  1420. *
  1421. * This is strcmp(), but ignoring case distinctions.  Found in most C libraries
  1422. * as stricmp().  Someday we should switch over.
  1423. */
  1424. int strCmpU(char s[], char t[])
  1425.   {
  1426.   int  i;
  1427.   i = 0;
  1428.   while (toUpper(s[i]) == toUpper(t[i]))
  1429.     {
  1430.     if (s[i++] == '\0')  return SAMESTRING ;
  1431.  
  1432.     }
  1433.   return  toUpper(s[i]) - toUpper(t[i]);
  1434.  
  1435.   }
  1436. /*
  1437. * crashout()
  1438. *
  1439. * This handles a fatal error, for library functions.
  1440. */
  1441. void crashout(char *str)
  1442.   {
  1443.   illegal(str);
  1444.  
  1445.   }
  1446. /*
  1447. * cfindMessage()
  1448. *
  1449. * This function gets all set up to do something with a message.
  1450. */
  1451. char cfindMessage(SECTOR_ID loc, MSG_NUMBER id)
  1452.   {
  1453.   long atol();
  1454.   MSG_NUMBER here;
  1455.   extern struct mBuf mFile1;
  1456.   startAt(msgfl, &mFile1, loc, 0);
  1457.   do
  1458.     {
  1459.     getMessage(getMsgChar, FALSE, FALSE, TRUE);
  1460.     here = atol(msgBuf.mbId);
  1461.  
  1462.     }
  1463.   while (here != id &&  mFile1.thisSector == loc);
  1464.   return (char)((here == id));
  1465.  
  1466.   }
  1467. /*
  1468. * CheckFloors()
  1469. *
  1470. * This function will check the floors.
  1471. */
  1472. void CheckFloors()
  1473.   {
  1474.   SYS_FILE     tempName;
  1475.   FILE   *flrfl;
  1476.   struct floor FloorBuf;
  1477.   struct floor *fptr;
  1478.   extern char  *R_W_ANY, *WRITE_ANY;
  1479.   int rover, cindex;
  1480.   int flag;
  1481.   char *cptr;
  1482.  
  1483.   makeSysName(tempName, "ctdlflr.sys", &cfg.floorArea);
  1484.  
  1485.   if ((flrfl = fopen(tempName, R_W_ANY)) == NULL)
  1486.     {
  1487.     printf(" %s not found, creating new file.\n", tempName);
  1488.     if ((flrfl = fopen(tempName, WRITE_ANY)) == NULL)
  1489.     illegal("?Can't create the floor file!");
  1490.  
  1491.     }
  1492.   /** create initial floor entry **/
  1493.   strCpy(FloorBuf.FlName, cfg.codeBuf + cfg.MainFloor);
  1494.   FloorBuf.FlInuse = TRUE;
  1495.   memset(FloorBuf.FlModerator, '\0',sizeof(label));
  1496.   /** write floor creation entry **/
  1497.   if( fwrite(&FloorBuf, sizeof FloorBuf, 1, flrfl) != 1)
  1498.     {
  1499.     printf("Write Error: %s\n",tempName);
  1500.     };
  1501.   totalBytes(&FloorSize, flrfl);
  1502.   FloorSize /= sizeof FloorBuf;
  1503.   printf("Current Floor file size is %ld entries\n",FloorSize);
  1504.   fclose(flrfl);
  1505.   /*  strip unused records  */
  1506.   if ((flrfl = fopen(tempName, READ_ANY)) == NULL)
  1507.     {
  1508.     illegal("?Can't read the floor file!");
  1509.     };
  1510.   fptr = (struct floor *)malloc(FloorSize * sizeof(struct floor) );
  1511.   /* get buffer for whole file */
  1512.   if( fptr == NULL )
  1513.     {
  1514.     free(fptr);
  1515.     illegal(" cannot allocate memory for a floor file!");
  1516.     };
  1517.   /* read whole file */
  1518.   if( fread( fptr, sizeof(struct floor), FloorSize, flrfl) != FloorSize )
  1519.     {
  1520.     free(fptr);
  1521.     illegal("Unable to read floor file!");
  1522.     };
  1523.   fclose(flrfl);
  1524.   /* Now, we know that there is at least one good record so we
  1525.      check from the end until we find a record in use
  1526.   */
  1527.   flag = TRUE;
  1528.   for( rover = 0; rover < FloorSize && fptr[rover].FlInuse  == TRUE; rover++)
  1529.     {
  1530.     /* validate that the Name are alpha characters and
  1531.        printable. Also test to see if In use.
  1532.     */
  1533.     cptr = &fptr[rover].FlModerator[0];
  1534.     if( ( *cptr >= 'a' && *cptr <= 'z' ) || ( *cptr >= 'A' && *cptr <= 'Z' ) )
  1535.       {
  1536.       printf("%20s is moderator for %s\n",fptr[rover].FlModerator,fptr[rover].FlName);
  1537.       }
  1538.     else
  1539.       {
  1540.       for( cindex = 0; cindex <20 ; cindex++)
  1541.         {
  1542.         cptr[cindex] = '\0';
  1543.         };
  1544.       };
  1545.     };
  1546.   FloorSize = rover;
  1547.   printf("New Floor file size is %ld entries\n",FloorSize);
  1548.   if ((flrfl = fopen(tempName, W_R_ANY)) == NULL)
  1549.     {
  1550.     free(fptr);
  1551.     illegal("?Can't Open the floor file to re-write!");
  1552.     };
  1553.   if( fwrite(fptr, sizeof(struct floor), FloorSize, flrfl) != FloorSize)
  1554.     {
  1555.     printf("Write Error: %s\n",tempName);
  1556.     };
  1557.   free(fptr);
  1558.   fclose(flrfl);
  1559.   }
  1560. /*
  1561. * CheckNet()
  1562. *
  1563. * This creates the Ctdlnet.sys if needed.
  1564. */
  1565. void CheckNet()
  1566.   {
  1567.   SYS_FILE      tempName;
  1568.   makeSysName(tempName, "ctdlnet.sys", &cfg.netArea);
  1569.   if ((netfl = fopen(tempName, READ_ANY)) == NULL)
  1570.     {
  1571.     printf(" %s not found, creating new file.\n", tempName);
  1572.     if ((netfl = fopen(tempName, WRITE_ANY)) == NULL)
  1573.     illegal("?Can't create the net file!");
  1574.  
  1575.     }
  1576.  
  1577.   }
  1578. /*
  1579. * NetParse()
  1580. *
  1581. * This function is responsible for parsing the network parameters.
  1582. */
  1583. static char NetParse(char *line, int *offset, char *var, int arg, int SetVal)
  1584.   {
  1585.   char temp[100];
  1586.   if (strCmpU(var, "#NewNetPrivs")    == SAMESTRING)
  1587.     {
  1588.     cfg.BoolFlags.NetDft      = arg;
  1589.     return TRUE;
  1590.  
  1591.     }
  1592.   else if (strCmpU(var, "#RouteMail")     == SAMESTRING)
  1593.     {
  1594.     cfg.BoolFlags.RouteMail = arg;
  1595.     return TRUE;
  1596.  
  1597.     }
  1598.   else if (strCmpU(var, "#SCAN-NET-MESSAGES") == SAMESTRING)
  1599.     {
  1600.     cfg.BoolFlags.NetScanBad = TRUE;
  1601.     return TRUE;
  1602.  
  1603.     }
  1604.   else if (strCmpU(var, "#SHARED-ROOMS")  == SAMESTRING)
  1605.     {
  1606.     if (SetVal)
  1607.       {
  1608.       if (SHARED_ROOMS != arg && cfg.netSize != 0)
  1609.       illegal(
  1610.       "SHARED-ROOMS parameter does not equal old value!");
  1611.       else
  1612.       SHARED_ROOMS = arg;
  1613.  
  1614.       }
  1615.     else
  1616.       {
  1617.       SHARED_ROOMS = arg;
  1618.  
  1619.       }
  1620.     return TRUE;
  1621.  
  1622.     }
  1623.   else if (strCmpU(var, "#NETWORK"   )    == SAMESTRING)
  1624.     {
  1625.     cfg.BoolFlags.netParticipant = arg;
  1626.     return TRUE;
  1627.     #ifdef NEED_LONGHAUL
  1628.  
  1629.     }
  1630.   else if (strCmpU(var, "#LONG-HAUL" )    == SAMESTRING)
  1631.     {
  1632.     cfg.BoolFlags.longHaul = arg;
  1633.     return TRUE;
  1634.     #endif
  1635.  
  1636.     }
  1637.   else if (strCmpU(var, "#NET_AREA_SIZE") == SAMESTRING)
  1638.     {
  1639.     cfg.sizeArea = arg;
  1640.     return TRUE;
  1641.  
  1642.     }
  1643.   else if (strCmpU(var, "#MAX_NET_FILE")    == SAMESTRING)
  1644.     {
  1645.     cfg.maxFileSize = arg;
  1646.     return TRUE;
  1647.  
  1648.     }
  1649.   else if (strCmpU(var, "#callOutSuffix") == SAMESTRING)
  1650.     {
  1651.     readString(line, &cfg.codeBuf[*offset], TRUE);
  1652.     cfg.netSuffix = *offset;
  1653.     while (cfg.codeBuf[*offset])
  1654.     (*offset)++;
  1655.     (*offset)++;
  1656.     return TRUE;
  1657.  
  1658.     }
  1659.   else if (strCmpU(var, "#callOutPrefix") == SAMESTRING)
  1660.     {
  1661.     readString(line, &cfg.codeBuf[*offset], TRUE);
  1662.     DefaultPrefix = *offset;
  1663.     while (cfg.codeBuf[*offset])
  1664.     (*offset)++;
  1665.     (*offset)++;
  1666.     return TRUE;
  1667.  
  1668.     }
  1669.   else if (strCmpU(var, "#DialOut300") == SAMESTRING)
  1670.     {
  1671.     readString(line, &cfg.codeBuf[*offset], TRUE);
  1672.     cfg.DialPrefixes[ONLY_300] = *offset;
  1673.     while (cfg.codeBuf[*offset])
  1674.     (*offset)++;
  1675.     (*offset)++;
  1676.     return TRUE;
  1677.  
  1678.     }
  1679.   else if (strCmpU(var, "#DialOut1200") == SAMESTRING)
  1680.     {
  1681.     readString(line, &cfg.codeBuf[*offset], TRUE);
  1682.     cfg.DialPrefixes[BOTH_300_1200] = *offset;
  1683.     while (cfg.codeBuf[*offset])
  1684.     (*offset)++;
  1685.     (*offset)++;
  1686.     return TRUE;
  1687.  
  1688.     }
  1689.   else if (strCmpU(var, "#DialOut2400") == SAMESTRING)
  1690.     {
  1691.     readString(line, &cfg.codeBuf[*offset], TRUE);
  1692.     cfg.DialPrefixes[TH_3_12_24] = *offset;
  1693.     while (cfg.codeBuf[*offset])
  1694.     (*offset)++;
  1695.     (*offset)++;
  1696.     return TRUE;
  1697.  
  1698.     }
  1699.   else if (strCmpU(var, "#DialOut4800") == SAMESTRING)
  1700.     {
  1701.     readString(line, &cfg.codeBuf[*offset], TRUE);
  1702.     cfg.DialPrefixes[B_4] = *offset;
  1703.     while (cfg.codeBuf[*offset])
  1704.     (*offset)++;
  1705.     (*offset)++;
  1706.     return TRUE;
  1707.  
  1708.     }
  1709.   else if (strCmpU(var, "#DialOut9600") == SAMESTRING)
  1710.     {
  1711.     readString(line, &cfg.codeBuf[*offset], TRUE);
  1712.     cfg.DialPrefixes[B_5] = *offset;
  1713.     while (cfg.codeBuf[*offset])
  1714.     (*offset)++;
  1715.     (*offset)++;
  1716.     return TRUE;
  1717.  
  1718.     }
  1719.   else if (strCmpU(var, "#DialOut14400") == SAMESTRING)
  1720.     {
  1721.     readString(line, &cfg.codeBuf[*offset], TRUE);
  1722.     cfg.DialPrefixes[B_6] = *offset;
  1723.     while (cfg.codeBuf[*offset])
  1724.     (*offset)++;
  1725.     (*offset)++;
  1726.     return TRUE;
  1727.  
  1728.     }
  1729.   else if (strCmpU(var, "#DialOut19200") == SAMESTRING)
  1730.     {
  1731.     readString(line, &cfg.codeBuf[*offset], TRUE);
  1732.     cfg.DialPrefixes[B_7] = *offset;
  1733.     while (cfg.codeBuf[*offset])
  1734.     (*offset)++;
  1735.     (*offset)++;
  1736.     return TRUE;
  1737.  
  1738.     }
  1739.   else if (strCmpU(var, "#nodeName" ) == SAMESTRING)
  1740.     {
  1741.     readString(line, &cfg.codeBuf[*offset], FALSE);
  1742.     NormStr(&cfg.codeBuf[*offset]);
  1743.     if (strLen(&cfg.codeBuf[*offset]) > 19)
  1744.     illegal("nodeName too long; must be less than 20");
  1745.     if (strchr(&cfg.codeBuf[*offset], '_') != NULL ||
  1746.     strchr(&cfg.codeBuf[*offset], '.') != NULL)
  1747.     illegal("The characters '.' and '_' are illegal in node names!");
  1748.     cfg.nodeName    = *offset;
  1749.     while (cfg.codeBuf[*offset]) /* step over string     */
  1750.     (*offset)++;
  1751.     (*offset)++;
  1752.     return TRUE;
  1753.  
  1754.     }
  1755.   else if (strCmpU(var, "#nodeId"   ) == SAMESTRING)
  1756.     {
  1757.     readString(line, &cfg.codeBuf[*offset], FALSE);
  1758.     if (strLen(&cfg.codeBuf[*offset]) > 19)
  1759.     illegal("nodeId too long; must be less than 20");
  1760.     cfg.nodeId      = *offset;
  1761.     while (cfg.codeBuf[*offset]) /* step over string     */
  1762.     (*offset)++;
  1763.     (*offset)++;
  1764.     return TRUE;
  1765.  
  1766.     }
  1767.   else if (strCmpU(var, "#MailHub"  ) == SAMESTRING)
  1768.     {
  1769.     readString(line, &cfg.codeBuf[*offset], FALSE);
  1770.     if (strLen(&cfg.codeBuf[*offset]) > 19)
  1771.     illegal("MailHub too long; must be less than 20");
  1772.     cfg.MailHub      = *offset;
  1773.     while (cfg.codeBuf[*offset]) /* step over string     */
  1774.     (*offset)++;
  1775.     (*offset)++;
  1776.     return TRUE;
  1777.  
  1778.     }
  1779.   else if (strCmpU(var, "#DomainDisplay") == SAMESTRING)
  1780.     {
  1781.     readString(line, cfg.DomainDisplay, FALSE);
  1782.     if (strLen(cfg.DomainDisplay) >= sizeof cfg.DomainDisplay)
  1783.     illegal("DomainDisplay is too long, must be less than 11");
  1784.     return TRUE;
  1785.  
  1786.     }
  1787.   else if (strCmpU(var, "#nodeDomain") == SAMESTRING)
  1788.     {
  1789.     readString(line, &cfg.codeBuf[*offset], FALSE);
  1790.     if (strLen(&cfg.codeBuf[*offset]) > 19)
  1791.     illegal("nodeDomain too long; must be less than 20");
  1792.     if (strchr(cfg.codeBuf + *offset, '_') != NULL ||
  1793.     strchr(cfg.codeBuf + *offset, '.') != NULL)
  1794.     illegal("Domain names cannot have '_' or '.' in them.");
  1795.     cfg.nodeDomain = *offset;
  1796.     while (cfg.codeBuf[*offset]) /* step over string     */
  1797.     (*offset)++;
  1798.     (*offset)++;
  1799.     return TRUE;
  1800.  
  1801.     }
  1802.   else if (strCmpU(var, "#ServeDomain") == SAMESTRING)
  1803.     {
  1804.     readString(line, temp, FALSE);
  1805.     if (strLen(temp) > 19)
  1806.     illegal("ServeDomain value is too long, must be less than 19 characters.");
  1807.     AddData(&Serves, strdup(temp), NULL, FALSE);
  1808.     cfg.DomainHandlers++;
  1809.     return TRUE;
  1810.  
  1811.     }
  1812.   return FALSE;
  1813.  
  1814.   }
  1815.  
  1816. void  Zap_Nodes_Message_Index()  /* zap last netted message */
  1817.   {
  1818.   int node, slot;
  1819.   for(node = 0; node < cfg.netSize; node++)
  1820.     {
  1821.     if( !netTab[node].ntflags.in_use )continue;
  1822.     getNet(node,&netBuf);
  1823.     for( slot=0; slot < SHARED_ROOMS; slot++)
  1824.       {
  1825.       if( !roomTab[netTabRoomSlot(node, slot)].rtflags.SHARED)continue;
  1826.       netTab[node].netTRooms[slot].lastMess = 0;
  1827.       netBuf.netRooms[slot].lastMess = 0;
  1828.       };
  1829.     putNet(node,&netBuf);
  1830.     };
  1831.  
  1832.   }
  1833.